home *** CD-ROM | disk | FTP | other *** search
-
- // PNM: declarations and routines
- // Version 2.02, 11.Feb.98
- // (c) 1997/98 by Stefan Diener
-
- #ifndef STIMP_PNM_INC
- #define STIMP_PNM_INC
-
- // We do not need the pseudo modes !
- #ifndef NO_PSEUDO_PGM_MODE
- #define NO_PSEUDO_PGM_MODE
- #endif
-
- #ifndef NO_PSEUDO_PPM_MODE
- #define NO_PSEUDO_PPM_MODE
- #endif
-
- #include <STIMP/pbm.c>
- #include <STIMP/pgm.c>
- #include <STIMP/ppm.c>
-
- struct PNM_Info
- {
- char type;
- unsigned int height;
- unsigned int width;
- unsigned int maxval;
- union
- {
- unsigned char *gray;
- struct
- {
- unsigned char *red;
- unsigned char *green;
- unsigned char *blue;
- } RGB;
- } DATEN;
- };
-
- #define DATA DATEN.gray
- #define redDATA DATEN.RGB.red
- #define greenDATA DATEN.RGB.green
- #define blueDATA DATEN.RGB.blue
-
- #define TYPE_PNM TYPE_PBM+TYPE_PGM+TYPE_PPM
-
- int ReadPNMFile(char *name, int mask, struct PNM_Info *info)
- // read a PNM-file
- {
- FILE *datei;
- char tempo[5];
- int type=0, zeile;
- long int i, j, k, elemente, gesamt, anzahl;
- unsigned char *srcR, *srcG, *srcB, *src;
- unsigned char *Puffer, *zeiger, zwisch;
-
- if (strcmp("-",name)==0) datei=stdin; // use stdin
- else
- {
- // really open a file
- datei=fopen(name,"rb");
- if (datei==0)
- {
- PrintMessage("File %s not found !", name);
- return 1;
- }
- }
-
- // set buffer size
- setvbuf(datei,0,_IOFBF,1000);
-
- // check type
- fgets(tempo, 4, datei);
- correct(tempo);
- if (strcmp(tempo,"P4")==0) type=TYPE_PBM;
- if (strcmp(tempo,"P5")==0) type=TYPE_PGM;
- if (strcmp(tempo,"P6")==0) type=TYPE_PPM;
-
- if (mask & type)
- {
- info->type=type;
-
- // read dimensions
- // skip comments !!!
- ReadComment(datei);
- fscanf(datei,"%i %i\n",&info->width,&info->height);
- gesamt=info->width*info->height;
-
- // read maxval if not a PBM image
- // skip comments !!!
- if (type!=TYPE_PBM)
- {
- ReadComment(datei);
- fscanf(datei,"%i\n",&info->maxval);
- }
-
- switch (type)
- {
- case TYPE_PBM : // PBM routine !!!!!!!!!!
- // print it on the screen
- PrintMessage("Reading %s (PBM, %ix%i)", name, info->width, info->height);
-
- // allocate memory for the picture
- info->DATA=NULL;
- info->DATA=(unsigned char *) malloc(gesamt*sizeof(unsigned char));
- if (info->DATA==NULL)
- {
- PrintMessage("No memory for the picture data left !");
- if (strcmp("-",name)!=0) fclose(datei);
- return 1;
- }
-
- // need an empty picture
- src=info->DATA;
- for (i=0;i<gesamt;i++) *src++=0;
-
- // initialize help variables
- src=info->DATA;
- zeile=info->width;
- if (zeile%8) zeile=zeile-(zeile%8)+8;
- zeile=zeile/8;
-
- // read picture data
- for (i=0; i<info->height; i++)
- {
- for (k=0; k<zeile; k++)
- {
- j=fgetc(datei);
- if (j==EOF)
- {
- PrintMessage("Unexpected end of file !");
- i=info->height;
- k=zeile;
- }
- else
- {
- zwisch=(unsigned char) j;
- for (j=7; j>=0; j--)
- {
- // Bit==0 => white, Bit==1 => black
- if (k*8+j<info->width) src[i*info->width+k*8+j]=((zwisch%2)?0:255);
- zwisch=zwisch>>1;
- }
- }
- }
- }
-
- // init maxval, even of not really needed
- info->maxval=255;
- break;
-
- case TYPE_PGM : // PGM routine !!!!!!!!!!
- // print it on the screen
- PrintMessage("Reading %s (PGM, %ix%i)", name, info->width, info->height);
-
- // allocate memory for picture data
- info->DATA=NULL;
- info->DATA=(unsigned char *) malloc(gesamt*sizeof(unsigned char));
- if (info->DATA==NULL)
- {
- PrintMessage("No memory for the picture data left !");
- if (strcmp("-",name)!=0) fclose(datei);
- return 1;
- }
-
- // need an empty picture
- src=info->DATA;
- for (i=0; i<gesamt; i++) *src++=0;
-
- // read picture data
- i=fread((void *) info->DATA, sizeof(unsigned char), gesamt, datei);
- if (i!=gesamt) PrintMessage("Error while reading the file !");
- break;
-
- case TYPE_PPM : // PPM routine !!!!!!!!!!
- // print it on the screen
- PrintMessage("Reading %s (PPM, %ix%i)", name, info->width, info->height);
-
- // allocate memory for the read buffer
- Puffer=NULL;
- Puffer=(unsigned char *) malloc(PPM_PUFFER_SIZE*sizeof(unsigned char));
- if (Puffer==NULL)
- {
- PrintMessage("No memory for the read buffer left !");
- if (strcmp("-",name)!=0) fclose(datei);
- return 1;
- }
-
- // allocate memory for red picture data
- info->redDATA=NULL;
- info->redDATA=(unsigned char *) malloc(gesamt*sizeof(unsigned char));
- if (info->redDATA==NULL)
- {
- PrintMessage("No memory for red picture data left !");
- free((void *) Puffer);
- if (strcmp("-",name)!=0) fclose(datei);
- return 1;
- }
-
- // allocate memory for green picture data
- info->greenDATA=NULL;
- info->greenDATA=(unsigned char *) malloc(gesamt*sizeof(unsigned char));
- if (info->greenDATA==NULL)
- {
- PrintMessage("No memory for green picture data left !");
- free((void *) Puffer);
- free((void *) info->redDATA);
- if (strcmp("-",name)!=0) fclose(datei);
- return 1;
- }
-
- // allocate memory for blue picture data
- info->blueDATA=NULL;
- info->blueDATA=(unsigned char *) malloc(gesamt*sizeof(unsigned char));
- if (info->blueDATA==NULL)
- {
- PrintMessage("No memory for blue picture data left !");
- if (strcmp("-",name)!=0) fclose(datei);
- free((void *) Puffer);
- free((void *) info->redDATA);
- free((void *) info->greenDATA);
- return 1;
- }
-
- // need an empty picture
- srcR=info->redDATA;
- srcG=info->greenDATA;
- srcB=info->blueDATA;
- for (i=0; i<gesamt; i++)
- {
- *srcR++=0;
- *srcG++=0;
- *srcB++=0;
- }
-
- // get pointers
- srcR=info->redDATA;
- srcG=info->greenDATA;
- srcB=info->blueDATA;
-
- // read picture data
- i=0;
- elemente=PPM_PUFFER_SIZE/3;
- while (i<gesamt)
- {
- anzahl=gesamt-i;
- if (anzahl>elemente) anzahl=elemente;
- j=fread((void *) Puffer, sizeof(unsigned char), anzahl*3, datei);
- if (j!=anzahl*3)
- {
- i=gesamt;
- PrintMessage("Error while reading the file !");
- }
- else
- {
- i+=anzahl;
- zeiger=Puffer;
- for (j=0; j<anzahl; j++)
- {
- *srcR++=*zeiger++;
- *srcG++=*zeiger++;
- *srcB++=*zeiger++;
- }
- }
- }
-
- // free buffer memory
- free((void *) Puffer);
- break;
- }
-
- // close file
- if (strcmp("-",name)!=0) fclose(datei);
- }
- else
- {
- if (strcmp("-",name)!=0) fclose(datei); // really close something
- PrintMessage("Wrong file type: %s !",name);
- return 1;
- }
-
- // ok
- return 0;
- }
-
- int WritePNMFile(char *name, struct PNM_Info *info)
- // write a PNM-file
- {
- int error=0;
- struct PBM_Info infoB;
- struct PGM_Info infoG;
- struct PPM_Info infoP;
-
- switch (info->type)
- {
- case TYPE_PBM: infoB.width=info->width;
- infoB.height=info->height;
- infoB.Data=info->DATA;
- error=WritePBMFile(name, &infoB);
- break;
-
- case TYPE_PGM: infoG.width=info->width;
- infoG.height=info->height;
- infoG.maxval=info->maxval;
- infoG.Data=info->DATA;
- error=WritePGMFile(name, &infoG);
- break;
-
- case TYPE_PPM: infoP.width=info->width;
- infoP.height=info->height;
- infoP.maxval=info->maxval;
- infoP.redData=info->redDATA;
- infoP.greenData=info->greenDATA;
- infoP.blueData=info->blueDATA;
- error=WritePPMFile(name, &infoP);
- break;
- }
-
- return error;
- }
-
- int CreatePNMArray(int y, int x, int typ, struct PNM_Info *info)
- // allocate memory for a PNM-picture
- {
- int error=0;
- struct PBM_Info infoB;
- struct PGM_Info infoG;
- struct PPM_Info infoP;
-
- switch (typ)
- {
- case TYPE_PBM: error=CreatePBMArray(y, x, &infoB);
- break;
-
- case TYPE_PGM: error=CreatePGMArray(y, x, &infoG);
- break;
-
- case TYPE_PPM: error=CreatePPMArray(y, x, &infoP);
- break;
-
- default: error=1;
- break;
- }
-
- if (error==0)
- {
- info->type=typ;
-
- switch (typ)
- {
- case TYPE_PBM: info->height=infoB.height;
- info->width=infoB.width;
- info->maxval=255;
- info->DATA=infoB.Data;
- break;
-
- case TYPE_PGM: info->height=infoG.height;
- info->width=infoG.width;
- info->maxval=infoG.maxval;
- info->DATA=infoG.Data;
- break;
-
- case TYPE_PPM: info->height=infoP.height;
- info->width=infoP.width;
- info->maxval=infoP.maxval;
- info->redDATA=infoP.redData;
- info->greenDATA=infoP.greenData;
- info->blueDATA=infoP.blueData;
- break;
- }
- }
-
- return error;
- }
-
- void FreePNMArray(struct PNM_Info *info)
- // free the memory of a PNM-picture
- {
- struct PBM_Info infoB;
- struct PGM_Info infoG;
- struct PPM_Info infoP;
-
- switch (info->type)
- {
- case TYPE_PBM: infoB.width=info->width;
- infoB.height=info->height;
- infoB.Data=info->DATA;
- FreePBMArray(&infoB);
- break;
-
- case TYPE_PGM: infoG.width=info->width;
- infoG.height=info->height;
- infoG.maxval=info->maxval;
- infoG.Data=info->DATA;
- FreePGMArray(&infoG);
- break;
-
- case TYPE_PPM: infoP.width=info->width;
- infoP.height=info->height;
- infoP.maxval=info->maxval;
- infoP.redData=info->redDATA;
- infoP.greenData=info->greenDATA;
- infoP.blueData=info->blueDATA;
- FreePPMArray(&infoP);
- break;
- }
- }
-
- #endif
-